package com.wise.service.cms.content.upload;

import com.microsoft.azure.storage.StorageException;
import com.microsoft.azure.storage.blob.BlockEntry;
import com.microsoft.azure.storage.blob.CloudBlobContainer;
import com.microsoft.azure.storage.blob.CloudBlockBlob;
import com.wise.framework.basic.FileUtil;
import com.wise.framework.exception.Excep;
import com.wise.model.content.UploadResult;
import com.wise.summer.v1.cms.content.upload.AddUpload;
import com.wise.summer.v1.cms.content.uploadresource.AddUploadResource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.summerframework.model.SummerService;
import org.summerframework.model.SummerServiceBean;

import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Objects;
import java.util.Random;

import static com.wise.model.content.ContentErrMsgs.Err_000100140019;

@Slf4j
@Service
@SummerService
public class AddUploadService implements SummerServiceBean<AddUpload> {
//    @Autowired
//    private OSSClient ossClient;

    @Autowired
    CloudBlobContainer cloudBlobContainer;

    @Value("${azure.file.block.split}")
    private int split;

    @Override
    public void sum(AddUpload summer) {
        MultipartFile file = (MultipartFile) summer.getFile();
        String extName = FileUtil.getExtName(file.getOriginalFilename());

        UploadResult uploadResult = uploadFileAsBlockBlob(file);

        if (Objects.isNull(summer.getResourceType())) {
            //资源类型默认为1（图片）
            summer.setResourceType(1);
        }
        AddUploadResource model = new AddUploadResource();
        model.setOriginResourceName(uploadResult.getOriginName());
        //model.setOssId(uploadResult.getName());
        model.setResourceName(uploadResult.getName());
        model.setGroupId(summer.getGroupId());
        model.setPath(uploadResult.getUrl());
        model.setResourcePath(summer.getResourcePath());
        model.setExtentionName(extName);
        model.setResourceType(summer.getResourceType());
        model.setFileSize(file.getSize());
        model.sum();

        AddUpload.UploadResult result = AddUpload.UploadResult.builder()
                .id(uploadResult.getName())
                .url(uploadResult.getUrl())
                .originResourceName(uploadResult.getOriginName())
                .build();
        summer.setSummerResult(result);
    }

    /**
     * 分块上传
     *
     * @param file 文件
     * @return 上传结果
     */
    private UploadResult uploadFileAsBlockBlob(MultipartFile file) {
        log.info("########################uploadFileAsBlockBlob############################");
        try (InputStream fileInputStream = file.getInputStream()) {
            //上传blob,生成随机文件名
            String originalFilename = file.getOriginalFilename();
            //获得图片后缀
            String substring = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();
            //根据时间戳设置唯一名称
            Random random = new Random();
            String name = random.nextInt(10000) + System.currentTimeMillis() + substring;

            //填入文件名 - 可以选择文件原名或生成的随机名
            CloudBlockBlob blockBlob = cloudBlobContainer.getBlockBlobReference(originalFilename);

            int blockNum = 0;
            ArrayList<BlockEntry> blockList = new ArrayList<>();

            //分块
            while (fileInputStream.available() > split * 1024 * 1024) {
                uploadBlock(blockNum, blockBlob, fileInputStream, split * 1024 * 1024, blockList);
                blockNum++;
            }
            long remain = file.getInputStream().available() - blockNum * split * 1024 * 1024;
            uploadBlock(blockNum, blockBlob, fileInputStream, remain, blockList);

            //分块上传
            blockBlob.commitBlockList(blockList);

            //获取文件路径
            UploadResult uploadResult = new UploadResult();
            uploadResult.setName(name);
            uploadResult.setUrl(blockBlob.getUri().toString());
            uploadResult.setOriginName(originalFilename);
            return uploadResult;
        } catch (StorageException | URISyntaxException | IOException e) {
            log.error(e.getMessage(), e);
            throw Excep.le(Err_000100140019);
        }
    }

    /**
     * 分块列表
     *
     * @param blockNum        块数量
     * @param blockBlob       分块
     * @param fileInputStream 输入流
     * @param size            单块大小
     * @param blockList       块列表
     */
    private void uploadBlock(int blockNum, CloudBlockBlob blockBlob,
                             InputStream fileInputStream, long size, ArrayList<BlockEntry> blockList) {
        try {
            String blockId = String.format("%05d", blockNum);
            String blockIdEncoded = Base64.getEncoder().encodeToString(blockId.getBytes());
            blockBlob.uploadBlock(blockIdEncoded, fileInputStream, size);
            log.info("[File Block Upload Success, blockId={}, size={}] ", blockId, size);
            blockList.add(new BlockEntry(blockIdEncoded));
        } catch (StorageException | IOException e) {
            log.error(e.getMessage(), e);
            throw Excep.le(Err_000100140019);
        }
    }

//    private String upload(MultipartFile file, String id){
//        try (InputStream inputStream = file.getInputStream()) {
//            String bucketName = ossConfiguration.getBucketName();
//            String endpoint = ossConfiguration.getEndpoint();
//
//            ossClient.putObject(bucketName, id, inputStream);
//            return HTTP +bucketName+"."+endpoint+"/"+id;
//        } catch (IOException e) {
//            log.error(e.getMessage(), e);
//            throw Excep.le(CmsErrMsgs.Err_000100140019);
//        }
//    }
}
